x
patches-own [ potential visited? elevation isGround]turtles-own [ path main? life ]globals [ screen-width terrain-noise random-terrain-offset min-pot max-pot column-elevations strike-heights ;; Sliders for controlling the noise strength, branch frequency, and new branch life ;; grain, branches, and branch-life are controlled by sliders]to setup clear-all set screen-width max-pxcor - min-pxcor + 1 set strike-heights[] ;;set terrain-noise (random-float (2 * terrain-noise-strength)) - terrain-noise-strength set random-terrain-offset random-float screen-width setup-potential-field set min-pot min [potential] of patches set max-pot max [potential] of patches ;; experimental code----------------------------------------------------------------- let temp-x min-pxcor repeat screen-width [ randomize-terrain-noise let wave sin(2 * peak-count * temp-x + random-terrain-offset) let temp-y min-pycor let random-elevation sea-level + (terrain-amplitude * wave) + terrain-noise repeat random-elevation [ ask patch temp-x temp-y[ set isGround true set potential max-pot set elevation pycor ] set temp-y (temp-y + 1) ] set temp-x (temp-x + 1) ] set column-elevations n-values screen-width [0] let diffusion-iterator min-pxcor repeat screen-width[ let column-elevation 0 ask patches with [pxcor = diffusion-iterator] [if isGround = true [set column-elevation (column-elevation + 1)]] ask patches with [pxcor = diffusion-iterator] [set potential (potential + column-elevation * column-elevation / 650 + column-elevation / 15)] set column-elevations replace-item (diffusion-iterator + max-pxcor) column-elevations column-elevation set diffusion-iterator (diffusion-iterator + 1) ] repeat 2 [diffuse potential 1.0] ;; Visualize potential gradient reset-atmosphere start-lightning-bolt reset-ticksendto setup-potential-field let noise-strength noise ask patches [ let base (max-pycor - pycor) let temp-noise (ifelse-value (noise-strength = 0) [ 0 ] [ random-float noise-strength - noise-strength / 2 ]) set potential base + temp-noise ]endto reset-atmosphere ask patches [ set visited? false ifelse isGround [ set pcolor 33 ] [ set pcolor scale-color blue potential min-pot max-pot ] ]endto start-lightning-bolt ;; Create main lightning bolt create-turtles 1 [ ;; Set starting position setxy random-float 180 - 90 (max-pycor) set color white set path [] set main? true set life 999 ask patch-here [ set pcolor white set visited? true ] ]endto go if not any? turtles [ reset-atmosphere start-lightning-bolt ] ask turtles [ ;; Branch lifespan if not main? [ set life life - 1 if life <= 0 [ die ] ] ;; Get downward-ish neighbors let neighbors-down neighbors with [ pycor <= [pycor] of myself or pxcor != [pxcor] of myself ] let current-pot [potential] of patch-here let cands neighbors-down with [ potential > current-pot and not visited? ] ;; If grain = 0, prefer directly below if possible let direct-down patch pxcor (pycor - 1) if noise = 0 and direct-down != nobody and not [visited?] of direct-down [ move-to direct-down ] ;; Otherwise, pick the best neighbor (only if grain > 0 or other conditions) ifelse any? cands [ let next ifelse-value (noise = 0) [ max-one-of cands [potential] ] [ max-one-of cands [potential + random-float 1.5] ] face next fd 1 ] [ ;; If no candidates and grain > 0, fallback slightly (only for main) if not any? cands and main? and pycor > min-pycor [ set heading 180 + random 60 - 30 fd 1 ask patch-here [ set pcolor white set visited? true ] ] ] ;; Update patch state ask patch-here [ set pcolor white set visited? true ] ;; Branching logic — disabled when grain = 0 if main? and noise > 0 [ let depth-frac (pycor - min-pycor) / (max-pycor - min-pycor) let branch-chance branches * depth-frac if random-float 1.0 < branch-chance [ hatch 1 [ set color white set path [] set main? false set life branch-life ;; Use branch-life slider to determine branch life rt random 120 - 60 fd 1 ask patch-here [ set pcolor white set visited? true ] ] ] ] ;; Die if done or touching ground if [elevation] of patch-here != 0 or (not main? and not any? cands) [ if main? [ set strike-heights lput (pycor + 90) strike-heights set-current-plot "Lightning Strikes" set-current-plot-pen "strike-height" plot ycor + 90 set-current-plot-pen "average-strike-height" plot mean strike-heights ] die ] ] tickendto randomize-terrain-noise set terrain-noise (random-float (2 * terrain-noise-strength)) - terrain-noise-strengthendto reset-simulation clear-all setupend